package com.wkbb.basic.controller.manage;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wkbb.basic.feign.DoorFeignService;
import com.wkbb.basic.model.UserFacePersonConfig;
import com.wkbb.basic.service.UserFacePersonConfigService;
import com.wkbb.basic.service.UserFaceService;
import com.wkbb.basic.service.YouTuService;
import com.wkbb.basic.thread.BasicCamTask;
import com.wkbb.basic.thread.BasicTask;
import com.wkbb.basic.utils.FileUtil;
import com.wkbb.basic.utils.ImageOfbase64UtilDto;
import com.wkbb.basic.utils.YouTuUtil;
import com.wkbb.common.base.BaseController;
import com.wkbb.common.config.ServiceConfig;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.VersionConstant;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.dto.basic.UserFaceDto;
import com.wkbb.common.utils.ExcelUtil;
import com.wkbb.common.utils.StringUtil;
import com.wkbb.common.utils.ThreadPoolUtil;
import com.wkbb.common.utils.UuIdUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author LilinsaveImportData
 */
@RestController
@Api(description = "用户个体人脸配置管理（后台管理）")
@RequestMapping("/basic/{apiVersion}/face/manage")
@Slf4j
public class UserFaceManageController extends BaseController {

    @Autowired
    private YouTuService youTuService;

    @Autowired
    private ServiceConfig serviceConfig;

    @Autowired
    private UserFacePersonConfigService userFacePersonConfigService;

    @Autowired
    private UserFaceService userFaceService;

    @Autowired
    private DoorFeignService doorFeignService;

    @ApiOperation(value = "新增或修改用户个体人脸配置")
    @RequestMapping(value = "/saveConfig", method = RequestMethod.POST)
    public ResultDTO<Long> saveConfig(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "用户个体人脸配置信息", required = true) @RequestBody UserFacePersonConfig userFacePersonConfig) {

        log.info("***********UserFacePersonConfigManageController.saveOrUpdate******apiVersion:{},userFacePersonConfig:{}", apiVersion, userFacePersonConfig);
        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }

        try {
            if (userFacePersonConfig.getOrgId() == null || userFacePersonConfig.getOrgId() == 0
                    || userFacePersonConfig.getUserId() == null || userFacePersonConfig.getUserId() == 0
                    || StringUtil.isNullOrBlank(userFacePersonConfig.getPersonId())) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            userFacePersonConfigService.saveConfig(userFacePersonConfig);

            return new ResultDTO<>(userFacePersonConfig.getId());
        } catch (Exception e) {
            log.error("***********UserFacePersonConfigManageController.saveOrUpdate******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "删除用户个体人脸配置")
    @RequestMapping(value = "/deleteConfig", method = RequestMethod.DELETE)
    public ResultDTO deleteConfig(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "用户个体人脸配置表ID", required = true) @RequestParam(name = "id", required = true) List<Long> ids) {

        log.info("***********UserFacePersonConfigManageController.delete******apiVersion:{},id:{},updateBy:{}", apiVersion, ids);

        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }

        try {
            userFacePersonConfigService.delete(ids, userDto.getName());

            return new ResultDTO();
        } catch (Exception e) {
            log.error("***********UserFacePersonConfigManageController.delete******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询用户个体人脸配置列表")
    @RequestMapping(value = "/getConfigList", method = RequestMethod.GET)
    public ResultDTO<List<UserFacePersonConfig>> getConfigList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId,
            @ApiParam(value = "0 学生人脸管理 1 教师人脸管理", required = true) @RequestParam(name = "type", required = true) Short type) {

        log.info("***********UserFacePersonConfigManageController.list******apiVersion:{},orgId:{},userId:{},type:{}", apiVersion, orgId, userId, type);

        try {
            Map<String, Object> params = new HashMap<>(2);
            if (orgId != null && orgId != 0) {
                params.put("orgId", orgId);
            }
            if (userId != null && userId != 0) {
                params.put("userId", userId);
            }

            return new ResultDTO<>(userFacePersonConfigService.getUserFacePersonConfigList(params, type));
        } catch (Exception e) {
            log.error("***********UserFacePersonConfigManageController.list******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "导入迁移人脸数据")
    @PostMapping(value = "importConfigExcelFile")
    public void importConfigExcelFile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @RequestParam("uploadFile") MultipartFile uploadFile, HttpServletRequest request, HttpServletResponse response) {

        UserDto userDto = getUserByLogin();
/*        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }*/

        InputStream in = null;
        try {
            //从登陆信息中解析出学校ID
            Long newOrgId = ((JSONArray) userDto.getRoleType()).getJSONObject(0).getLong("orgId");
            if (null == newOrgId) {
                log.error("----从登陆信息中解析出学校ID为空---");
                /*      return new ResultDTO<>(false);*/
            }
            if (uploadFile.isEmpty()) {
                throw new Exception("文件不存在！");
            }
            in = uploadFile.getInputStream();
            List<Object[]> data = ExcelUtil.importExcel(in);
            if (null != data && data.size() > 0) {
                for (Object[] objects : data) {
                    log.info(JSONObject.toJSONString(objects));
                }
                BasicTask basicTask = new BasicTask(userFacePersonConfigService, userDto, data);
                ThreadPoolUtil.addTask(basicTask);
                // List<Object> resultDTO = userFacePersonConfigService.saveImportData(userDto, data);
                //return new ResultDTO<>(resultDTO);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //  return new ResultDTO<>();
    }

    @ApiOperation(value = "智慧校园导入迁移人脸数据")
    @PostMapping(value = "/importCamConfigExcelFile")
    public void importCamConfigExcelFile(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @RequestParam("uploadFile") MultipartFile uploadFile,
            HttpServletRequest request, HttpServletResponse response) {

        UserDto userDto = getUserByLogin();
/*        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }*/

        InputStream in = null;
        try {
            //从登陆信息中解析出学校ID
            Long newOrgId = ((JSONArray) userDto.getRoleType()).getJSONObject(0).getLong("orgId");
            if (null == newOrgId) {
                log.error("----从登陆信息中解析出学校ID为空---");
                /*      return new ResultDTO<>(false);*/
            }
            if (uploadFile.isEmpty()) {
                throw new Exception("文件不存在！");
            }
            in = uploadFile.getInputStream();
            List<Object[]> data = ExcelUtil.importExcel(in);
            if (null != data && data.size() > 0) {
                for (Object[] objects : data) {
                    log.info(JSONObject.toJSONString(objects));
                }
                BasicCamTask basicCamTask = new BasicCamTask(userFacePersonConfigService, userDto, data);
                ThreadPoolUtil.addTask(basicCamTask);
                // List<Object> resultDTO = userFacePersonConfigService.saveImportData(userDto, data);
                //return new ResultDTO<>(resultDTO);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //  return new ResultDTO<>();
    }

    @ApiOperation(value = "删除机构下所有个体和人脸")
    @RequestMapping(value = "/deletePerSonIdByOrgId", method = RequestMethod.DELETE)
    public ResultDTO deletePerSonIdByOrgId(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {

        log.info("***********UserFacePersonConfigManageController.deletePerSonIdByOrgId******apiVersion:{},orgId:{}}", apiVersion, orgId);

        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }
        try {
            log.info("********开始删除机构下所有个体和人脸********");
            userFacePersonConfigService.deletePerSonIdByOrgId(orgId);
            log.info("********删除机构下所有个体和人脸********");
        } catch (Exception e) {
            log.error("***********UserFacePersonConfigManageController.deletePerSonIdByOrgId******", e);
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
        return new ResultDTO();
    }

    /**
     * 人脸上传入口
     */
    @ApiOperation(value = "人脸上传入口(后台管理系统接口)")
    @PostMapping(value = "addUserFace")
    public ResultDTO<Object> addUserFace(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "第一张正脸照片", required = true) @RequestParam(name = "picUrla", required = true) String picUrla,
            @ApiParam(value = "第二张正脸照片", required = false) @RequestParam(name = "picUrlb", required = false) String picUrlb,
            @ApiParam(value = "个体ID", required = true) @RequestParam(name = "userCode", required = true) String userCode,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "集团ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "userId", required = true) Long userId,
            @ApiParam(value = "人脸相似度(相似度为整数值:范围80-99)", required = false) @RequestParam(name = "similar", required = false) Short similar
    ) {
        log.info("***********UserFaceManageController.addUserFace******apiVersion:{},picUrla:{},picUrlb:{},userCode:{},orgId:{},accountId:{},userId:{}", apiVersion, picUrla, picUrlb, userCode, orgId, accountId, userId);
        UserDto userDto = getUserByLogin();
        if (userDto == null) {
            return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
        }
        try {
            if (StringUtil.isEmpty(picUrla) || StringUtil.isEmpty(userCode) || null == orgId || null == accountId || null == userId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            String result = youTuService.saveUserFace(new ImageOfbase64UtilDto(picUrla, FileUtil.encodeImageToBase64(new URL(picUrla))), userCode, orgId, accountId, userId, similar);
            log.info("-----addUserFace-----上传人脸结果-----{}", result);
            if (JSON.isValid(result)) {
                if (YouTuUtil.FACENOTCOMPLETE.equals(JSONObject.parseObject(result).get("errorcode"))) {

                    return new ResultDTO<>(ErrorCode.FACENOTCOMPLETE);
                } else if (YouTuUtil.PERSONIDNOTEXIST.equals(JSONObject.parseObject(result).get("errorcode"))) {

                    return new ResultDTO<>(ErrorCode.PERSONIDNOTEXIST);
                } else if (YouTuUtil.ERRORCODETYPE.equals(JSONObject.parseObject(result).get("errorcode"))) {

                    if (null != JSONObject.parseObject(result).get("result") && serviceConfig.getFaceCompare().compareTo(new BigDecimal(JSONObject.parseObject(result).get("result").toString())) == 1) {
                        return new ResultDTO<>(ErrorCode.ACCURACYCOMPARE);
                    }

                    if (null != JSONObject.parseObject(result).get("face_num") && Integer.parseInt(JSONObject.parseObject(result).get("face_num").toString()) == 0) {
                        return new ResultDTO<>(ErrorCode.CHECKFACEERROR);
                    }

                    //如果优图返回成功并且ret_codes数组里面有值,返回对应错误码
                    if (null != JSONObject.parseObject(result).get("ret_codes") && JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).size() > 0) {

                        if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110106)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120007);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110107)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120008);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110108)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120009);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110109)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120010);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110110)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACEERROR);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110111)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120011);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110112)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120012);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110113)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120013);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110114)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120014);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110115)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120015);

                        } else if (JSONObject.parseArray(JSONObject.parseObject(result).get("ret_codes").toString()).get(0).equals(YouTuUtil.ERRORCODETYPE110116)) {
                            return new ResultDTO<>(ErrorCode.CHECKFACE2120016);
                        }
                    }
                } else if (YouTuUtil.ERRORCODETYPE110110.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACEERROR);

                } else if (YouTuUtil.ERRORCODETYPE110114.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.FACETYPEERROR);

                } else if (YouTuUtil.ERRORCODETYPE110106.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120007);

                } else if (YouTuUtil.ERRORCODETYPE110107.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120008);

                } else if (YouTuUtil.ERRORCODETYPE110108.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120009);

                } else if (YouTuUtil.ERRORCODETYPE110109.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120010);

                } else if (YouTuUtil.ERRORCODETYPE110111.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120011);

                } else if (YouTuUtil.ERRORCODETYPE110112.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120012);

                } else if (YouTuUtil.ERRORCODETYPE110113.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120013);

                } else if (YouTuUtil.ERRORCODETYPE110115.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120015);

                } else if (YouTuUtil.ERRORCODETYPE110116.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120016);

                } else if (YouTuUtil.ERRORCODETYPE1305.equals(JSONObject.parseObject(result).get("errorcode"))) {
                    return new ResultDTO<>(ErrorCode.CHECKFACE2120017);
                }

            } else {
                return new ResultDTO<>(ErrorCode.ADDORMODIFYFACEERROR);
            }
            return new ResultDTO<Object>(result);
        } catch (Exception e) {
            log.error("***********UserFaceManageController.addUserFace******", e);
            return new ResultDTO<Object>(false);
        }
    }

    @ApiOperation(value = "批量注册人脸到阅面算法")
    @PostMapping(value = "batchRegistFaceToReadSense")
    public void batchRegistFaceToReadSense(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "开始时间，格式yyyy-MM-dd", required = false) @RequestParam(name = "beginTime", required = false) String beginTime,
            @ApiParam(value = "结束时间，格式yyyy-MM-dd", required = true) @RequestParam(name = "endTime", required = true) String endTime) {

        UserDto userDto = getUserByLogin();

        try {
            List<UserFaceDto> list = userFaceService.getUserFaceListByUpdateTime(beginTime, endTime);
            log.info("-----batchRegistFaceToReadSense-----批量注册人脸到阅面算法-----beginTime:{},endTime:{},size:{}", beginTime, endTime, list.size());
            for (int i = 0; i < list.size(); i++) {
                try {
                    ResultDTO<Object> resultDTO = doorFeignService.batchFaceRegist(null, list.get(i).getFaceImgUrl(), list.get(i).getPersonId(), null, UuIdUtil.getGroupIds(serviceConfig.getProfilesActive(), String.valueOf(list.get(i).getOrgId())));
                    log.info("-----batchRegistFaceToReadSense-----批量注册人脸到阅面算法-----i:{},resultDTO:{}", i, JSONObject.toJSONString(resultDTO));
                    Thread.sleep(10);//测试服务器内存不足
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //  return new ResultDTO<>();
    }
}